package com.freewater.javabase.demo.network.proxy;

import com.google.common.collect.Lists;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.nio.charset.Charset;
import java.util.List;

public class ProxySelectorDemo {

    public static void main(String[] args) throws IOException {
        LocalProxySelector proxySelector = new LocalProxySelector();
        ProxySelector.setDefault(proxySelector);
        URL url = new URL("https://www.google.com");
        readContent(url);
    }

    private static void readContent(URL url) throws IOException {
        final URLConnection urlConnection = url.openConnection();
        urlConnection.setConnectTimeout(10 * 1000);
        try (final InputStream inputStream = urlConnection.getInputStream();
             final ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            int read = -1;
            byte[] bytes = new byte[1024];
            while ((read = inputStream.read(bytes)) != -1) {
                bos.write(bytes);
            }
            bos.flush();
            final String content = bos.toString(Charset.forName("utf-8"));
            System.out.println(content.substring(0, 100));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    // 自定义ProxySelector
    static class LocalProxySelector extends ProxySelector {

        private List<URI> failedUris = Lists.newArrayList();

        @Override
        public List<Proxy> select(URI uri) {
            List<Proxy> proxies = Lists.newArrayList();
            if (failedUris.contains(uri)
                    || (!"http".equals(uri.getScheme())
                    && !"https".equals(uri.getScheme()))) {
                proxies.add(Proxy.NO_PROXY);
            } else {
                InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 1080);
                Proxy proxy = new Proxy(Proxy.Type.SOCKS, inetSocketAddress);
                proxies.add(proxy);
            }
            return proxies;
        }

        @Override
        public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
            System.out.println("uri access failed: " + uri);
            failedUris.add(uri);
        }
    }
}
